#ifndef __SIMU_EC800_H_
#define __SIMU_EC800_H_

#include <time.h>
#include <stdio.h>
#include <stdint.h>
#include "pthread.h"
#include "semaphore.h"
#include "ghttp.h"
#include "mqtt_c.h"
#include "posix_sockets.h"
#include "ql_osi_def.h"
#include "ql_api_common.h"

// #pragma warning(disable : 4996)
#pragma warning(disable : 4819) //警告	C4819	该文件包含不能在当前代码页(936)中表示的字符。请将该文件保存为 Unicode 格式以防止数据丢失
#define KG_SIMULATOR
// LOG/Debug Macro -----------------------------------------------------------------------------------------------
	#define _SIMU_FILE_NAME (strrchr(__FILE__, '\\')+1)
// format and print log
#define SimuLog(msg, ...) printf("******** %s:%d:%s: "msg"\n",  _SIMU_FILE_NAME, __LINE__, __FUNCTION__, ##__VA_ARGS__)

#define TRUE 1
#define FALSE 0
typedef int    QlOSStatus;
#define QL_SUCCESS (0)

enum
{
	OSI_LOG_LEVEL_NEVER,  ///< only used in control, for not to output trace
	OSI_LOG_LEVEL_ERROR,  ///< error
	OSI_LOG_LEVEL_WARN,   ///< warning
	OSI_LOG_LEVEL_INFO,   ///< information
	OSI_LOG_LEVEL_DEBUG,  ///< for debug
	OSI_LOG_LEVEL_VERBOSE ///< verbose
};
#define QL_LOG_LEVEL_NEVER		OSI_LOG_LEVEL_NEVER
#define QL_LOG_LEVEL_ERROR		OSI_LOG_LEVEL_ERROR
#define QL_LOG_LEVEL_WARN		OSI_LOG_LEVEL_WARN
#define QL_LOG_LEVEL_INFO		OSI_LOG_LEVEL_INFO
#define QL_LOG_LEVEL_DEBUG		OSI_LOG_LEVEL_DEBUG
#define QL_LOG_LEVEL_VERBOSE	OSI_LOG_LEVEL_VERBOSE



#include "ql_uart.h"




#define QL_GPIO_ERRCODE_BASE (QL_COMPONENT_BSP_GPIO<<16)

typedef enum
{
	QL_GPIO_SUCCESS = QL_SUCCESS,

	QL_GPIO_EXECUTE_ERR = 1 | QL_GPIO_ERRCODE_BASE,
	QL_GPIO_INVALID_PARAM_ERR,
	QL_GPIO_OPEN_ERR,
	QL_GPIO_CONFIG_ERR,
	QL_GPIO_CALLBACK_ERR,
	QL_GPIO_LEVEL_TRIGGER_ERR,
	QL_GPIO_MEM_NULL_ERR,
	QL_GPIO_SET_DRVING_ERR,
}ql_errcode_gpio;

/**
 * GPIO number
 */
typedef enum
{
	GPIO_0 = 0,
	GPIO_1,
	GPIO_2,
	GPIO_3,
	GPIO_4,
	GPIO_5,
	GPIO_6,
	GPIO_7,
	GPIO_8,
	GPIO_9,
	GPIO_10,
	GPIO_11,
	GPIO_12,
	GPIO_13,
	GPIO_14,
	GPIO_15,
	GPIO_16,
	GPIO_17,
	GPIO_18,
	GPIO_19,
	GPIO_20,
	GPIO_21,
	GPIO_22,
	GPIO_23,
	GPIO_24,
	GPIO_25,
	GPIO_26,
	GPIO_27,
	GPIO_28,
	GPIO_29,
	GPIO_30,
	GPIO_31,
	GPIO_32,
	GPIO_33,
	GPIO_34,
	GPIO_35,
	GPIO_36,
	GPIO_37,
	GPIO_38,
	GPIO_39,
	GPIO_40,
	GPIO_41,
	GPIO_42,
	GPIO_43,
	GPIO_44,
	GPIO_45,
	GPIO_46,
	GPIO_47,
	GPIO_MAX
}ql_GpioNum;

/**
 * GPIO direction
 */
typedef enum
{
	GPIO_INPUT,
	GPIO_OUTPUT
}ql_GpioDir;

/**
 * GPIO output level
 */
typedef enum
{
	LVL_LOW,
	LVL_HIGH
}ql_LvlMode;

/**
 * GPIO input pull mode
 */
typedef enum
{
	PULL_NONE,
	PULL_DOWN,
	PULL_UP
}ql_PullMode;

/*========================================================================
 *  Enumeration Definition
 *========================================================================*/
 //dev component detail errcode, 4 bytes
#define QL_DEV_ERRCODE_BASE (QL_COMPONENT_STATE_INFO<<16)

typedef enum
{
	QL_DEV_SUCCESS = QL_SUCCESS,

	QL_DEV_EXECUTE_ERR = 1 | QL_DEV_ERRCODE_BASE,
	QL_DEV_MEM_ADDR_NULL_ERR,
	QL_DEV_INVALID_PARAM_ERR,
	QL_DEV_BUSY_ERR,
	QL_DEV_SEMAPHORE_CREATE_ERR,
	QL_DEV_SEMAPHORE_TIMEOUT_ERR,
	QL_DEV_HANDLE_INVALID_ERR,

	QL_DEV_CFW_CFUN_GET_ERR = 15 | QL_DEV_ERRCODE_BASE,
	QL_DEV_CFW_CFUN_SET_CURR_COMM_FLAG_ERR = 18 | QL_DEV_ERRCODE_BASE,
	QL_DEV_CFW_CFUN_SET_COMM_ERR,
	QL_DEV_CFW_CFUN_SET_COMM_RSP_ERR,
	QL_DEV_CFW_CFUN_RESET_BUSY = 25 | QL_DEV_ERRCODE_BASE,
	QL_DEV_CFW_CFUN_RESET_CFW_CTRL_ERR,
	QL_DEV_CFW_CFUN_RESET_CFW_CTRL_RSP_ERR,

	QL_DEV_IMEI_GET_ERR = 33 | QL_DEV_ERRCODE_BASE,

	QL_DEV_SN_GET_ERR = 36 | QL_DEV_ERRCODE_BASE,

	QL_DEV_UID_READ_ERR = 39 | QL_DEV_ERRCODE_BASE,

	QL_DEV_TEMP_GET_ERR = 50 | QL_DEV_ERRCODE_BASE,

	QL_DEV_WDT_CFG_ERR = 53 | QL_DEV_ERRCODE_BASE,

	QL_DEV_HEAP_QUERY_ERR = 56 | QL_DEV_ERRCODE_BASE,

	QL_DEV_AUTHCODE_READ_ERR = 90 | QL_DEV_ERRCODE_BASE,
	QL_DEV_AUTHCODE_ADDR_NULL_ERR,

	QL_DEV_READ_WIFI_MAC_ERR = 100 | QL_DEV_ERRCODE_BASE,              //read wifi mac address nv error
} ql_errcode_dev_e;

#define QL_DEV_SUCCESS (0)
#define QL_UART_SUCCESS (0)
#define OSI_MAKE_LOG_TAG(a, b, c, d) ((unsigned)(a) | ((unsigned)(b) << 7) | ((unsigned)(c) << 14) | ((unsigned)(d) << 21))
#define QL_LOG_OUTPUT_LEVEL		QL_LOG_LEVEL_INFO
#define QL_LOG_TAG_OPEN		    OSI_MAKE_LOG_TAG('Q', 'O', 'P', 'N')
#define QL_LOG_TAG_QDEV		    OSI_MAKE_LOG_TAG('Q', 'D', 'E', 'V')
#define QL_LOG_TAG_SMS		    OSI_MAKE_LOG_TAG('Q', 'S', 'M', 'S')
#define QL_LOG_TAG_QVOLTE		OSI_MAKE_LOG_TAG('Q', 'V', 'L', 'T')
#define QL_LOG_TAG_DATACALL		OSI_MAKE_LOG_TAG('Q', 'D', 'C', 'A')
#define QL_LOG_TAG_NW		    OSI_MAKE_LOG_TAG('Q', 'L', 'N', 'W')
#define QL_LOG_TAG_QPBK		    OSI_MAKE_LOG_TAG('Q', 'P', 'B', 'K')
#define QL_LOG_TAG_QSIM		    OSI_MAKE_LOG_TAG('Q', 'S', 'I', 'M')
#define QL_LOG_TAG_QVIMADAPT	OSI_MAKE_LOG_TAG('Q', 'V', 'S', 'A')
#define QL_LOG_TAG_QUSBNET		OSI_MAKE_LOG_TAG('Q', 'U', 'N', 'T')

typedef enum
{
	QUEC_APP_EVENT_ID_MIN = 1 | (QL_COMPONENT_OSI << 16),
	QUEC_TEST_EVENT_ID_1,
	QUEC_TEST_EVENT_ID_2,
	QUEC_TEST_EVENT_ID_3,
	QUEC_KERNEL_FEED_DOG,

	//network
	QUEC_NW_SIGNAL_QUALITY_IND = 1 | (QL_COMPONENT_NETWORK << 16),
	QUEC_NW_VOICE_REG_STATUS_IND,
	QUEC_NW_DATA_REG_STATUS_IND,
	QUEC_NW_NITZ_TIME_UPDATE_IND,
	QUEC_NW_JAMMING_DETECT_IND,
	QUEC_NW_CAUSE_IND,
	QUEC_NW_CELL_INFO_REQ,
	QUEC_NW_CELL_INFO_IND,
	//datacall    
	QUEC_DATACALL_ACT_RSP_IND = 1 | (QL_COMPONENT_NETWORK_MANAGE << 16),
	QUEC_DATACALL_DEACT_RSP_IND,
	QUEC_DATACALL_PDP_DEACTIVE_IND,

	//usbnet
	QUEC_USBNET_START_RSP_IND = 1 | (QL_COMPONENT_NETWORK_USBNET << 16),	//response of usbnet start
	QUEC_USBNET_DEACTIVE_IND,											//usbnet down, The cause may be loss of network coverage or detached by the network
	QUEC_USBNET_PORT_CONNECT_IND,										//usb plug in
	QUEC_USBNET_PORT_DISCONNECT_IND,									//usb pull out

	//uart
	QUEC_UART_RX_RECV_DATA_IND = 1 | (QL_COMPONENT_BSP_UART << 16),
	QUEC_UART_RX_OVERFLOW_IND,
	QUEC_UART_TX_FIFO_COMPLETE_IND,
	QUEC_UART_TX_COMPLETE_APP_IND,
	QUEC_UART_RX_RECV_DATA_APP_IND,

	//usb
	QUEC_USB_LINESTATE_IND = 1 | (QL_COMPONENT_BSP_USB << 16),		//only used for kernel, to handle usb linestate


	//uac
	QUEC_USB_AUDIO_CREATE_DONE = 2000 | (QL_COMPONENT_BSP_USB << 16),	//UAC created ok, only used for kernel
	QUEC_USB_AUDIO_DATA_IN = 2001 | (QL_COMPONENT_BSP_USB << 16),	//UAC received data, only used for kernel	
	QUEC_USB_AUDIO_START_PLAY = 2002 | (QL_COMPONENT_BSP_USB << 16), //UAC start receive data, only used for kernel	
	QUEC_USB_AUDIO_STOP_PLAY = 2003 | (QL_COMPONENT_BSP_USB << 16),  //UAC stop receive data, only used for kernel	
	QUEC_USB_AUDIO_START_RECORD = 2004 | (QL_COMPONENT_BSP_USB << 16), //UAC start send data to host, only used for kernel	
	QUEC_USB_AUDIO_STOP_RECORD = 2005 | (QL_COMPONENT_BSP_USB << 16), //UAC stop send data to host, only used for kernel	

	//bt
	QUEC_BT_START_STATUS_IND = 1 | (QL_COMPONENT_BSP_BT << 16),     //bt/ble start
	QUEC_BT_STOP_STATUS_IND,                                    //bt/ble stop
	QUEC_BT_BLE_RESET_IND,                                      //bt/ble reset.need to stop bt and restart
	QUEC_BT_VISIBILE_IND,                                       //
	QUEC_BT_HIDDEN_IND,
	QUEC_BT_SET_LOCALNAME_IND,
	QUEC_BT_SET_LOCALADDR_IND,
	QUEC_BT_INQUIRY_IND,
	QUEC_BT_INQUIRY_END_IND,
	QUEC_BT_BOND_IND,
	QUEC_BT_BOND_STATE_IND,
	QUEC_BT_CONNECT_IND,
	QUEC_BT_DISCONNECT_IND,

	QUEC_BT_HFP_CONNECTION_IND,
	//ble
		//all:server and client can recieve this event
		//server:only server can recieve this event
		//client:only client can recieve this event
	QUEC_BLE_CONNECT_IND = 100 | (QL_COMPONENT_BSP_BT << 16),       //all:ble connect
	QUEC_BLE_DISCONNECT_IND,                                    //all:ble disconnect
	QUEC_BLE_UPDATE_CONN_PARAM_IND,                             //all:ble update connection parameter

	QUEC_BLESCAN_REPORT_IND,                                    //client:ble gatt cliet scan and report other devices

	QUEC_BLE_GATT_MTU,                                          //all:ble connection mtu
	QUEC_BLE_GATT_RECV_IND,                                     //server:when ble client write characteristic value or descriptor,server get the notice
	QUEC_BLE_GATT_RECV_READ_IND,                                //server:when ble client read characteristic value or descriptor,server get the notice
	QUEC_BLE_GATT_RECV_NOTIFICATION_IND,                        //client:client recieve notification   
	QUEC_BLE_GATT_RECV_INDICATION_IND,                          //client:client recieve indication
	QUEC_BLE_GATT_SEND_END,                                     //server send notification,and recieve send end notice

	QUEC_BLE_GATT_START_DISCOVER_SERVICE_IND,                   //client:start discover service
	QUEC_BLE_GATT_DISCOVER_SERVICE_IND,                         //client:discover service
	QUEC_BLE_GATT_DISCOVER_CHARACTERISTIC_DATA_IND,             //client:discover characteristic
	QUEC_BLE_GATT_DISCOVER_CHARA_DESC_IND,                      //client:discover characteristic descriptor
	QUEC_BLE_GATT_CHARA_WRITE_WITH_RSP_IND,                     //client:write characterisctc value with response
	QUEC_BLE_GATT_CHARA_WRITE_WITHOUT_RSP_IND,                  //client:write characteristic value without response
	QUEC_BLE_GATT_CHARA_READ_IND,                               //client:read characteristic value by hanlde
	QUEC_BLE_GATT_CHARA_READ_BY_UUID_IND,                       //client:read characteristic value by uuid
	QUEC_BLE_GATT_CHARA_MULTI_READ_IND,                         //client:read miltiple characteristic value
	QUEC_BLE_GATT_DESC_WRITE_WITH_RSP_IND,                      //client:wirte characteristic descriptor
	QUEC_BLE_GATT_DESC_READ_IND,                                //client:read characteristic descriptor
	QUEC_BLE_GATT_ATT_ERROR_IND,                                //client:attribute error
	QUEC_BLE_GATT_STATE_CHANGE_IND,                             //server:通道改变
	QUEC_BLE_GATT_SEND_NODIFY_IND,                              //server:通知server线程从缓存里读取数据发送，只在标准版本使用

	QUEC_BT_HFP_CONNECT_IND = 200 | (QL_COMPONENT_BSP_BT << 16),     //bt hfp connected
	QUEC_BT_HFP_DISCONNECT_IND,                                 //bt hfp disconnected
	QUEC_BT_HFP_CALL_IND,                                       //bt hfp call state callback
	QUEC_BT_HFP_CALL_SETUP_IND,                                 //bt hfp call setup state callback
	QUEC_BT_HFP_NETWORK_IND,                                    //bt hfp network state callback
	QUEC_BT_HFP_NETWORK_SIGNAL_IND,                             //bt hfp network signal callback
	QUEC_BT_HFP_BATTERY_IND,                                    //bt hfp battery level callback
	QUEC_BT_HFP_CALLHELD_IND,                                   //bt hfp callheld state callback
	QUEC_BT_HFP_AUDIO_IND,                                      //bt hfp audio state callback
	QUEC_BT_HFP_VOLUME_IND,                                     //bt hfp volume type callback
	QUEC_BT_HFP_NETWORK_TYPE_IND,                               //bt hfp network type callback
	QUEC_BT_HFP_RING_IND,                                       //bt hfp ring indication callback
	QUEC_BT_HFP_CODEC_IND,                                      //bt hfp codec type callback

	QUEC_BT_A2DP_AUDIO_CONFIG_IND = 300 | (QL_COMPONENT_BSP_BT << 16),  //bt a2dp audio config callback
	QUEC_BT_A2DP_AUDIO_STATE_START_IND,							    //bt a2dp audio state start callback
	QUEC_BT_A2DP_AUDIO_STATE_STOPPED_IND,						    //bt a2dp audio state stop callback
	QUEC_BT_A2DP_CONNECTION_STATE_CONNECTED_IND,				    //bt a2dp connect callback
	QUEC_BT_A2DP_CONNECTION_STATE_DISCONNECTED_IND,				    //bt a2dp disconnect callback

	QUEC_BT_AVRCP_CONNECTION_STATE_CONNECTED_IND = 400 | (QL_COMPONENT_BSP_BT << 16),		//bt avrcp connect callback
	QUEC_BT_AVRCP_CONNECTION_STATE_DISCONNECTED_IND,			                        //bt avrcp disconnect callback
	QUEC_BT_AVRCP_VOLUME_CHANGE_IND,							                        //bt avrcp volume change callback


	QUEC_BT_SPP_CONNECT_IND = 500 | (QL_COMPONENT_BSP_BT << 16),//bt spp connected  callback
	QUEC_BT_SPP_DISCONNECT_IND,             //bt spp disconnected   callback
	QUEC_BT_SPP_REVDATA_IND,                //bt spp receive data callback

	//led_cfg(network status for netlight)
	QUEC_LEDCFG_EVENT_IND = 1 | (QL_COMPONENT_BSP_PWM << 16),
	QUEC_LEDCFG_CB_CREATE_IND,
	QUEC_VIRTUAL_PWM_EVENT,
	QUEC_LEDCFG_VIRT_PWM_EVENT,
	QUEC_HR_VIRT_PWM_EVENT,
	//sleep
	QUEC_SLEEP_ENETR_AUTO_SLEPP = 1 | (QL_COMPONENT_PM_SLEEP << 16),
	QUEC_SLEEP_EXIT_AUTO_SLEPP = 2 | (QL_COMPONENT_PM_SLEEP << 16),

	//power
	QUEC_SLEEP_QUICK_POWER_DOWM = 1 | (QL_COMPONENT_PM << 16),
	QUEC_SLEEP_NORMAL_POWER_DOWM = 2 | (QL_COMPONENT_PM << 16),
	QUEC_SLEEP_QUICK_RESET = 3 | (QL_COMPONENT_PM << 16),
	QUEC_SLEEP_NORMAL_RESET = 4 | (QL_COMPONENT_PM << 16),
	QUEC_SLEEP_FAST_POWEROFF = 5 | (QL_COMPONENT_PM << 16),

	//sim
	QL_PBK_INIT_OK_IND = 1 | (QL_COMPONENT_SIM << 16),
	QUEC_SIM_APREADY_CMD_IND = 2 | (QL_COMPONENT_SIM << 16),

	//vsim adapt
	QUEC_VSIM_ADAPT_POWERON_IND = 1 | (QL_COMPONENT_VSIM_ADAPT << 16),
	QUEC_VSIM_ADAPT_RDY_IND = 2 | (QL_COMPONENT_VSIM_ADAPT << 16), //FOR standard AT solution, not cared in OPEN project.
	QUEC_VSIM_ADAPT_VSIM_AT_IND = 3 | (QL_COMPONENT_VSIM_ADAPT << 16), //FOR standard AT solution, not cared in OPEN project. //old feature, don't used

	//pwrkey
	QUEC_PWRKEY_SHUTDOWN_START_IND = 1 | (QL_COMPONENT_BSP_KEYPAD << 16),
	QUEC_PWRKEY_PRESS_IND,
	QUEC_PWRKEY_RELEASE_IND,
	QUEC_PWRKEY_LONGPRESS_IND,

	//wifiscan
	QUEC_WIFISCAN_EVENT_DO = 1 | (QL_COMPONENT_BSP_WIFISCAN << 16),
	QUEC_WIFISCAN_EVENT_TIMEOUT = 2 | (QL_COMPONENT_BSP_WIFISCAN << 16),
	QUEC_WIFISCAN_EVENT_ASYNC_IND = 5 | (QL_COMPONENT_BSP_WIFISCAN << 16),
	//gnss
	QUEC_GNSS_REC_NMEA_IND = 1 | (QL_COMPONENT_BSP_GNSS << 16),
	QUEC_GNSS_POWER_EVENT_REQ,
	QUEC_GNSS_RESTART_EVENT_REQ,
	QUEC_GNSS_MODE_AND_AGNSS_IND,
	QUEC_GNSS_AGPS_IND,
	QUEC_GNSS_START_RF_REQ,
	QUEC_GNSS_SLEEP_IND,
	QUEC_GNSS_FIX_IND,
	QUEC_GNSS_MODE_CONVER_IND,
	QUEC_GNSS_HSL_ABORT_IND,
	QUEC_GNSS_HSL_RECOVERY_IND,
	QUEC_GNSS_STARTMODE_IND,
	QUEC_GNSS_STATE_IND,

	//lvgl
	QUEC_LVGL_QUIT_IND = 1 | (QL_COMPONENT_BSP_LVGL << 16),

	//virt at
	QUEC_VIRT_AT_RX_RECV_DATA_IND = 1 | (QL_COMPONENT_BSP_VIRT_AT << 16),

	//sd
	QUEC_SDDET_EVENT_IND = 1 | (QL_COMPONENT_STORAGE_SDEMMC << 16),

	//tts
	QUEC_TTS_START_PLAY = 1 | (QL_COMPONENT_AUDIO_TTS << 16),

	//headset_det
	QUEC_HEADSET_DET_EVENT_IND = 1 | (QL_COMPONENT_AUDIO_HEADSET << 16),


	//stk
	QUEC_STK_PROACTIVE_CMD_IND = 1 | (QL_COMPONENT_STK << 16),
	QUEC_STK_NO_PROACTIVE_CMD_IND = 2 | (QL_COMPONENT_STK << 16),
	QUEC_STK_TIMEOUT_IND = 3 | (QL_COMPONENT_STK << 16),
	QUEC_STK_SIM_LOST_IND = 4 | (QL_COMPONENT_STK << 16),

	// tcpip app
	QUEC_TCPIP_APP_PDP_EVT_IND = 1 | (QL_COMPONENT_LWIP << 16),
	//AT Command
	QUEC_RECEIVE_NEW_AT = 1 | (QL_COMPONENT_AT << 16),
	QUEC_AT_RESP = 2 | (QL_COMPONENT_AT << 16),
	QUEC_AT_RECEIVE_DATA = 3 | (QL_COMPONENT_AT << 16),
	QUEC_AT_FINISH = 4 | (QL_COMPONENT_AT << 16),
	QUEC_AT_RECEIVE_CB = 5 | (QL_COMPONENT_AT << 16),
	QUEC_AT_BYPASS_NEW_DATA = 6 | (QL_COMPONENT_AT << 16),
	QUEC_AT_CMUX_NEW_DATA = 7 | (QL_COMPONENT_AT << 16),
	QUEC_AT_CMUX_SEND_DATA = 8 | (QL_COMPONENT_AT << 16),
	QUEC_AT_CMUX_CLOSE = 9 | (QL_COMPONENT_AT << 16),

	//queclocator
	QUEC_LBS_EVENT_WIFISCAN_REC = 1 | (QL_COMPONENT_LWIP_LBS << 16),

	//BSP GPIO
	QUEC_GPIOCTRL_EVENT_IND = 1 | (QL_COMPONENT_BSP_GPIO << 16),
	QUEC_GPIOCTRL_TIMER_EVENT_IND = 2 | (QL_COMPONENT_BSP_GPIO << 16),

	//ETHERNET
	QUEC_ETHERNET_APP_INT = 1 | (QL_COMPONENT_ETHERNET << 16),
	QUEC_ETHERNET_APP_DATA_OUTPUT = 2 | (QL_COMPONENT_ETHERNET << 16),
	QUEC_ETHERNET_APP_STATUS_CHECK = 3 | (QL_COMPONENT_ETHERNET << 16),


	//
	//next is reserved for app to add event id!
	//
	QL_EVENT_APP_START = 1 | (QL_COMPONENT_APP_START << 16),//app event start

	QL_EVEN_MAX = 0xFFFF | (QL_COMPONENT_MAX << 16),//event max
}ql_api_event_id_e;

// 多任务系统功能 -------------------------------------------------------------------------------------------
#define QL_OSI_SUCCESS 0
typedef pthread_t* ql_task_t;
typedef pthread_mutex_t ql_mutex_t;
extern QlOSStatus ql_rtos_mutex_create(ql_mutex_t* mutexRef);
extern QlOSStatus ql_rtos_mutex_lock(ql_mutex_t mutexRef, uint32_t timeout);
// extern QlOSStatus ql_rtos_mutex_try_lock(ql_mutex_t mutexRef);
extern QlOSStatus ql_rtos_mutex_unlock(ql_mutex_t mutexRef);
extern QlOSStatus ql_rtos_mutex_delete(ql_mutex_t mutexRef);
// simulate functions 最多支持32线程，每个线程队列深度16
typedef struct
{
	uint32_t id;     ///< event identifier
	size_t param1; ///< 1st parameter
	size_t param2; ///< 2nd parameter
	size_t param3; ///< 3rd parameter
} ql_event_t;
typedef struct {
	ql_task_t taskRef;
	//int max_cnt;		// 最大记录条数
	int cnt;			// 实际有多少条记录
	int pos;			// 指向第一条记录存放起始位置
	ql_mutex_t self_mutex;
	ql_event_t buffs[16];		// Circular Stack 记录数组地址
} simu_task_queue_t;
extern QlOSStatus ql_rtos_event_send(ql_task_t	task_ref, ql_event_t* event);
extern QlOSStatus ql_event_wait(ql_event_t* event_strc, uint32_t timeout);

extern int ql_rtos_task_create
(
	ql_task_t* taskRef, 			 /* OS task reference										   				  */
	unsigned int   stackSize,			 /* number of bytes in task stack area						   				  */
	unsigned char 		   priority,			 /* task priority, users should use the defination in APP_ThreadPriority_e,
											and not recommand beyond APP_PRIORITY_ABOVE_NORMAL 						  */
	char* taskName,			 /* task name, no more than 16 bytes, exceed 16 bytes will only save 16 bytes */
	void	   (*taskStart)(void*),	 /* pointer to task entry point 			 				   				  */
	void* argv,				 /* task entry argument pointer 							   				  */
	unsigned int         event_count,          /* the max event count that the task can waiting to process   				  */
	...
);
typedef sem_t ql_sem_t;
typedef enum
{
	QL_WAIT_FOREVER = 0xFFFFFFFFUL,
	QL_NO_WAIT = 0
} ql_wait_e;
extern int ql_rtos_semaphore_create
(
	ql_sem_t* semaRef,       /* OS semaphore reference                     	*/
	unsigned int      initialCount    /* initial count of the semaphore             	*/
);
extern int ql_rtos_semaphore_wait
(
	ql_sem_t  	semaRef,       /* OS semaphore reference                     	*/
	unsigned int      timeout    	   /* QL_WAIT_FOREVER, QL_NO_WAIT, or timeout	*/
);
extern int ql_rtos_semaphore_release
(
	ql_sem_t   semaRef        /* OS semaphore reference						*/
);
extern int ql_rtos_semaphore_delete
(
	ql_sem_t   semaRef        /* OS semaphore reference                  		*/
);
extern int ql_rtos_task_delete
(
	ql_sem_t taskRef		/* OS task reference	*/
);




typedef enum
{
	RESET_QUICK,
	RESET_NORMAL
}ql_ResetMode;
extern int ql_power_reset(int reset_mode);
extern void ql_rtos_task_sleep_s(unsigned int s);
extern void ql_rtos_task_sleep_ms(unsigned int ms);
extern int ql_dev_get_imei(char* p_imei, size_t imei_len, uint8_t nSim);
extern int ql_dev_get_imei(char* p_imei, size_t imei_len, uint8_t nSim);
extern int ql_sim_get_iccid(uint8_t nSim, char* iccid, size_t iccid_len);
extern int ql_nw_get_csq(uint8_t nSim, unsigned char* csq);


// data call相关模拟功能 -----------------------------------------------------------------------------------------------
#define QL_PDP_TYPE_IP   1           
/** This is the aligned version of ip4_addr_t,
   used as local variable, on the stack, etc. */
   struct ip4_addr {
	   uint32_t addr;
   };
/** ip4_addr_t uses a struct for convenience only, so that the same defines can
* operate both on ip4_addr_t as well as on ip4_addr_p_t. */
typedef struct ip4_addr ip4_addr_t;
struct v4_address_status
{
	ip4_addr_t ip;
	ip4_addr_t pri_dns;
	ip4_addr_t sec_dns;
};
struct v4_info
{
	int state;                          //dial status
	struct v4_address_status addr;      //IPv4 address information
};
typedef struct
{
	int profile_idx;
	int ip_version;
	struct v4_info v4;
}ql_data_call_info_s;
extern int ql_datacall_get_sim_profile_is_active(uint8_t nSim, int profile_idx);
extern int ql_network_register_wait(uint8_t nSim, unsigned int timeout_s);
extern int ql_set_data_call_asyn_mode(uint8_t nSim, int profile_idx, int enable);
extern int ql_start_data_call(uint8_t nSim, int profile_idx, int ip_version, char* apn_name, char* username, char* password, int auth_type);
extern int ql_stop_data_call(uint8_t nSim, int profile_idx);
extern int ql_get_data_call_info(uint8_t nSim, int profile_idx, ql_data_call_info_s* info);
extern int ql_dev_get_modem_fun(uint8_t* func, uint8_t nSim);

typedef enum
{
    QL_RTC_SUCCESS = 0,

    QL_RTC_INVALID_PARAM_ERR = 0x82120001,
    QL_RTC_SET_TIME_ERROR,
    QL_RTC_SET_CB_ERR,
    QL_RTC_ENABLE_ALARM_ERR,
    QL_RTC_REMOVE_ALARM_ERR,
    QL_RTC_SET_CFG_ERR
}ql_errcode_rtc_e;

typedef enum
{
	QUEC_DISABLE = 0,
	QUEC_ENABLE  = 1,
} quec_enable_e;
typedef struct ql_rtc_cfg_struct {
  quec_enable_e nv_cfg;  //开机是否读取nv保存的时间，作为初始rtc值(ENABLE:读取,DISABLE不读取,默认不读取)
  quec_enable_e rtc_cfg; //开机是否读取rtc寄存器的时间，作为初始rtc值，若VBAT电源断开，时间将重置成2000-1-1(ENABLE:读取,DISABLE不读取,默认不读取)
  quec_enable_e nwt_cfg; //连接基站后，是否同步基站时间到rtc时间(ENABLE:同步,DISABLE不同步,默认同步)
  uint8_t tz_cfg;  //注网后时区配置(0：保持原配置，注网后更新为网络时区, 1：注网后，保持原有时区, 2：注网后，重置时区为0, 默认0)
}ql_rtc_cfg_t;
extern ql_errcode_rtc_e ql_rtc_get_cfg(ql_rtc_cfg_t *ql_rtc_cfg);
extern ql_errcode_rtc_e ql_rtc_set_cfg(ql_rtc_cfg_t *ql_rtc_cfg);
typedef struct tm ql_rtc_time_t;

extern int ql_rtc_get_time(ql_rtc_time_t* tm);
extern ql_errcode_rtc_e ql_rtc_set_time(ql_rtc_time_t* tm);
extern int ql_rtc_get_localtime(ql_rtc_time_t* ql_tm);

typedef FILE* QFILE;
extern QFILE ql_fopen(const char *file_name, const char *mode);
extern int ql_fwrite(void * buffer, size_t size, size_t num, QFILE fd);
#define ql_fclose fclose
#define ql_fread fread
// #define ql_fwrite fwrite
extern int ql_fsize(QFILE fp);
extern int ql_mkdir(const char* path, unsigned int mode);
extern int ql_remove(const char* file_name);
extern int ql_fseek(QFILE fd, long offset, int origin);
extern int ql_file_exist(const char* file_name);
extern int ql_fputs(const char* chr, QFILE fd);
extern char* ql_fgets(char* str, int n, QFILE fd);
extern int ql_stat(const char* file_name, struct stat* st);
extern int ql_frewind(QFILE fd);

typedef enum
{
	QL_FOTA_SUCCESS = 0,
} ql_errcode_fota_e;
typedef enum
{
	QL_FOTA_FINISHED = 0,   // FOTA 升级操作完成
	QL_FOTA_NOT_EXIST,      // 没有fota更新包，这不是一个错误状态，需要下载fota更新包
	QL_FOTA_READY,          // fota更新包已经被设置准备状态，等待更新
	QL_FOTA_STATUS_INVALID, // FOTA状态是无效的
	QL_FOTA_PACK_CHECK_ERR, // FOTA包校验失败
} ql_fota_result_e;
extern ql_errcode_fota_e ql_fota_get_result(ql_fota_result_e* p_fota_result);
extern ql_errcode_fota_e ql_fota_file_reset(int del_image);
extern ql_errcode_fota_e ql_fota_image_verify(char* PackFileName);



#define QL_HTTP_OK 0
#define HTTP_SUCCESS 0
typedef enum {
	HTTP_INFO_RESPONSE_CODE = 0,
	HTTP_INFO_LOCATION = 1,
	HTTP_INFO_DATE = 2,
	HTTP_INFO_CONTENT_LEN = 3,
	HTTP_INFO_CHUNK_ENCODE = 4,
	HTTP_INFO_ACCEPT_RANGES = 5,
	HTTP_INFO_PARTION_LEN = 6,
}http_info_e;
typedef enum {
	HTTP_EVENT_SESSION_ESTABLISH = 0,
	HTTP_EVENT_RESPONE_STATE_LINE = 1,
	HTTP_EVENT_SESSION_DISCONNECT = 2,
}http_event_id_e;
typedef enum {
	HTTP_METHOD_NONE,
	HTTP_METHOD_GET,
	HTTP_METHOD_POST,
	HTTP_METHOD_PUT,
	HTTP_METHOD_HEAD,
	HTTP_METHOD_LAST
} http_method_e;
typedef enum {
	HTTP_CLIENT_OPT_PDPCID = 1,
	HTTP_CLIENT_OPT_SSLCTXID = 2,
	HTTP_CLIENT_OPT_BASIC_AUTH = 3,
	HTTP_CLIENT_OPT_REQUEST_HEADER = 4,
	HTTP_CLIENT_OPT_WRITE_HEADER = 5,
	HTTP_CLIENT_OPT_INTERVAL_TIME = 6,
	HTTP_CLIENT_OPT_METHOD = 7,
	HTTP_CLIENT_OPT_WRITE_FUNC = 8,
	HTTP_CLIENT_OPT_WRITE_DATA = 9,
	HTTP_CLIENT_OPT_READ_FUNC = 10,
	HTTP_CLIENT_OPT_READ_DATA = 11,
	HTTP_CLIENT_OPT_UPLOAD_LEN = 12,
	HTTP_CLIENT_OPT_URL = 13,
	HTTP_CLIENT_OPT_SSL_VERIFY_LEVEL = 14,
	HTTP_CLIENT_OPT_SSL_CACERT_PATH = 15,
	HTTP_CLIENT_OPT_SSL_OWNCERT_PATH = 16,
	HTTP_CLIENT_OPT_URI = 17,
	HTTP_CLIENT_OPT_SIM_ID = 18,
	HTTP_CLIENT_OPT_SSL_SNI = 19,
	HTTP_CLIENT_OPT_SSL_VERSION = 20,
	HTTP_CLIENT_OPT_SSL_HS_TIMEOUT = 21,
	HTTP_CLIENT_OPT_SSL_IGNORE_LOCALTM = 22,
	HTTP_CLIENT_OPT_SSL_IGNORE_INVALID_CERT_SIGN = 23,
	HTTP_CLIENT_OPT_SSL_IGNORE_CERT_ITEM = 24,
	HTTP_CLIENT_OPT_SSL_IGNORE_MULTI_CERTCHAIN_VERIFY = 25,
	HTTP_CLIENT_OPT_RAW_REQUEST = 26,
	HTTP_CLIENT_OPT_RAW_FILE = 27,
}http_option_e;

typedef ghttp_request * http_client_t;
typedef void(*http_client_event_cb_t)(http_client_t* client, int evt, int evt_code, void* arg);
typedef int(*http_client_write_data_cb_t)(http_client_t* client, void* arg, char* data, int size, unsigned char end);
typedef int(*http_client_read_data_cb_t)(http_client_t* client, void* arg, char* data, int size);
extern int  ql_httpc_new(http_client_t* client, http_client_event_cb_t cb, void* arg);
extern int  ql_httpc_setopt(http_client_t* client, int opt_tag, ...);
extern int  ql_httpc_perform(http_client_t* client);
extern int  ql_httpc_release(http_client_t* client);
extern int  ql_httpc_getinfo(http_client_t* client, int info, ...);


// WIFI相关模拟功能 -----------------------------------------------------------------------------------------------
#define QL_WIFI_SCAN_MAX_TIME (5000) //max scan time for a channel
#define QL_WIFI_SCAN_MIN_TIME (120) //min scan time for a channel
#define QL_WIFI_SCAN_DEFAULT_TIME (600)//default scan time for a channel
#define QL_WIFISCAN_ERRCODE_BASE (QL_COMPONENT_BSP_WIFISCAN<<16)
#define QL_WIFISCAN_CHANNEL_ALL  (0)

#define QL_WIFI_SCAN_MAX_AP_CNT (300)//max wifi ap count to scan
#define QL_WIFI_SCAN_MIN_AP_CNT (1)//min wifi ap count to scan
#define QL_WIFI_SCAN_DEFAULT_AP_CNT (10)//default wifi ap count to scan

#define QL_WIFI_SCAN_MAX_ROUND (10)//max round to scan
#define QL_WIFI_SCAN_MIN_ROUND (1)//min round to scan
#define QL_WIFI_SCAN_DEFAULT_ROUND (1)//default round to scan

typedef enum
{
	QL_WIFISCAN_SUCCESS  				        = 0,
    
    QL_WIFISCAN_EXECUTE_ERR                     = 0x820d0001,
    QL_WIFISCAN_MEM_ADDR_NULL_ERR,
    QL_WIFISCAN_INVALID_PARAM_ERR,
    QL_WIFISCAN_SEMAPHORE_WAIT_ERR,
    QL_WIFISCAN_MUTEX_TIMEOUT_ERR,
    
    QL_WIFISCAN_OPEN_FAIL,
    QL_WIFISCAN_BUSY_ERR,
    QL_WIFISCAN_ALREADY_OPEN_ERR,
    QL_WIFISCAN_NOT_OPEN_ERR,
    QL_WIFISCAN_HW_OCCUPIED_ERR,
    QL_WIFISCAN_NO_SET_CB_ERR,
    QL_WIFISCAN_SSID_FORMAT_CONVERT_ERR,   //ssid格式转换错误
} ql_errcode_wifi_scan_e;
typedef struct
{
	uint32_t bssid_low;  ///< mac address low
	uint16_t bssid_high; ///< mac address high
	uint8_t channel;	 ///< channel id
	int8_t rssival; 	 ///< signal strength
    uint16_t reserved;
    uint16_t ssidlen;    ///< ssid len, unit byte
    uint8_t ssid[32*2+1];///< 底层默认返回最大32字节的utf-8格式的ssid,如果需要转换格式,数据长度会变大。
                         ///< beacon帧上SSID字段最长就是32字节
} 
ql_wifi_ap_info_s;
typedef struct
{
	uint32_t ap_cnt;
	ql_wifi_ap_info_s* ap_infos;
} ql_wifiscan_result_s;
typedef struct
{
	uint32_t msg_id;
	uint32_t msg_err_code;
	void* msg_data;
} ql_wifiscan_ind_msg_s;

extern ql_errcode_wifi_scan_e ql_wifiscan_option_set(uint16_t expect_ap_cnt, uint8_t round, uint16_t scan_channel, uint32_t channel_time);
extern ql_errcode_wifi_scan_e ql_wifiscan_open(void);
extern ql_errcode_wifi_scan_e ql_wifiscan_close(void);
extern ql_errcode_wifi_scan_e ql_wifiscan_do(uint16_t *p_ap_cnt, ql_wifi_ap_info_s *p_ap_infos);

// base station相关模拟功能 -----------------------------------------------------------------------------------------------
typedef enum
{
	QL_NW_SUCCESS                   = 0,
    QL_NW_EXECUTE_ERR               = 0x86000001,
    QL_NW_MEM_ADDR_NULL_ERR,         
    QL_NW_INVALID_PARAM_ERR,
    QL_NW_CFW_CFUN_GET_ERR,
    QL_NW_CFUN_DISABLE_ERR,
    QL_NW_CFW_NW_STATUS_GET_ERR,
    QL_NW_NOT_SEARCHING_ERR,
    QL_NW_NOT_REGISTERED_ERR,
    QL_NW_CFW_GPRS_STATUS_GET_ERR,
    QL_GPRS_NOT_SEARCHING_ERR,
    QL_GPRS_NOT_REGISTERED_ERR,
    QL_NW_CFW_NW_QUAL_GET_ERR,
    QL_NW_CFW_OPER_ID_GET_ERR,
    QL_NW_CFW_OPER_NAME_GET_ERR,
    QL_NW_CFW_OPER_SET_ERR,
    QL_NW_SIM_ERR,
    QL_NW_NO_MEM_ERR,
    QL_NW_SEMAPHORE_CREATE_ERR,
    QL_NW_SEMAPHORE_TIMEOUT_ERR,
    QL_NW_NITZ_NOT_UPDATE_ERR,
    QL_NW_CFW_EMOD_START_ERR,
    QL_NW_OPERATOR_NOT_ALLOWED,
    QL_NW_CFW_RRCRel_SET_ERR,
    QL_NW_BLACK_CELL_FULL_ERR,
    QL_NW_PLMNFORMAT_CONVERT_UNFOUND,
}ql_nw_errcode_e;
#define QL_NW_CELL_MAX_NUM 7                //maxinum number of cell infomation (include serving cell and neighbour cell)
typedef struct
{
    int flag;                               //Cell type, 0:serving, 1:neighbor
    int cid;                                //Cell ID, (0 indicates that the cellid is not received)
    int mcc;                                
    int mnc;                                
    int lac;                                //Location area code
    int arfcn;                              //Absolute RF channel number
    char bsic;                              //Base station identity code. (0 indicates information is not present)
	int rssi;		                        //Receive signal strength, Value range: rxlev-111 for dbm format
	char mnc_len;
	char RX_dBm;                            //Received power
}ql_nw_gsm_cell_info_s;
typedef struct
{
    int flag;                               //Cell type, 0:serving, 1:neighbor
    int cid;                                //Cell ID, (0 indicates that the cellid is not received)
    int mcc;                                
    int mnc;                                
    int tac;                                //Tracing area code
    int pci;                                //Physical cell ID
    int earfcn;                             //E-UTRA absolute radio frequency channel number of the cell. RANGE: 0 TO 65535
	int rssi;		                        //Receive signal strength, Value range: rsrp-140 for dbm format
	char mnc_len;
	char RX_dBm;                            //Received power
}ql_nw_lte_cell_info_s;
typedef struct 
{
    int                     gsm_info_valid;                     //0: GSM cell information is invalid   1: GSM cell information is valid
    int                     gsm_info_num;                       //GSM cell number
    ql_nw_gsm_cell_info_s   gsm_info[QL_NW_CELL_MAX_NUM];       //GSM cell information (Serving and neighbor)
    int                     lte_info_valid;                     //0: LTE cell information is invalid   1: LTE cell information is valid
    int                     lte_info_num;                       //LTE cell number
    ql_nw_lte_cell_info_s   lte_info[QL_NW_CELL_MAX_NUM];       //LTE cell information (Serving and neighbor)
}ql_nw_cell_info_s;
extern ql_nw_errcode_e ql_nw_get_cell_info(uint8_t nSim, ql_nw_cell_info_s *cell_info);


// 串口相关模拟功能 -----------------------------------------------------------------------------------------------
typedef enum
{
	QL_PORT_NONE = -1,
	QL_UART_PORT_1,
	QL_UART_PORT_2,
	QL_UART_PORT_3,
	QL_UART_PORT_4,
	QL_UART_PORT_5,
	QL_UART_PORT_6,
	QL_USB_PORT_AT,
	QL_USB_PORT_MODEM,
	QL_USB_PORT_NMEA,
	QL_USB_PORT_PRINTER = QL_USB_PORT_NMEA,	//when enabled usb printer, usb nmea port will be enumerated as a printing device
	QL_PORT_MAX,
}ql_uart_port_number_e;
typedef enum
{
	QL_UART_BAUD_AUTO = 0,               //自适应波特率
	QL_UART_BAUD_1200 = 1200,
	QL_UART_BAUD_2400 = 2400,
	QL_UART_BAUD_4800 = 4800,
	QL_UART_BAUD_9600 = 9600,
	QL_UART_BAUD_14400 = 14400,
	QL_UART_BAUD_19200 = 19200,
	QL_UART_BAUD_28800 = 28800,
	QL_UART_BAUD_33600 = 33600,
	QL_UART_BAUD_38400 = 38400,
	QL_UART_BAUD_57600 = 57600,
	QL_UART_BAUD_115200 = 115200,
	QL_UART_BAUD_230400 = 230400,
	QL_UART_BAUD_250000 = 250000,
	QL_UART_BAUD_460800 = 460800,
	QL_UART_BAUD_500000 = 500000,
	QL_UART_BAUD_921600 = 921600,
	QL_UART_BAUD_1000000 = 1000000,
	QL_UART_BAUD_1843200 = 1843200,
	QL_UART_BAUD_2000000 = 2000000,
	//QL_UART_BAUD_2100000    = 2100000,
	//QL_UART_BAUD_3686400    = 3686400,      //only support uart2/3
	//QL_UART_BAUD_4000000    = 4000000,      //only support uart2/3
	//QL_UART_BAUD_4468750    = 4468750       //only support uart2/3
}ql_uart_baud_e;

typedef enum
{
	QL_UART_DATABIT_7 = 7,
	QL_UART_DATABIT_8 = 8,      //8910 ARM UART hardware only support 8bit Data
}ql_uart_databit_e;

typedef enum
{
	QL_UART_STOP_1 = 1,
	QL_UART_STOP_2 = 2,
}ql_uart_stopbit_e;

typedef enum
{
	QL_UART_PARITY_NONE,
	QL_UART_PARITY_ODD,
	QL_UART_PARITY_EVEN,
}ql_uart_paritybit_e;
typedef enum
{
	QL_FC_NONE = 0,
	QL_FC_HW,
}ql_uart_flowctrl_e;

typedef struct
{
	ql_uart_baud_e baudrate;
	ql_uart_databit_e data_bit;
	ql_uart_stopbit_e stop_bit;
	ql_uart_paritybit_e parity_bit;
	ql_uart_flowctrl_e flow_ctrl;
}ql_uart_config_s;

typedef void (*ql_uart_callback)(uint32_t ind_type, ql_uart_port_number_e port, uint32_t size);
extern int ql_uart_open(ql_uart_port_number_e port);
extern int ql_uart_set_dcbconfig(ql_uart_port_number_e port, ql_uart_config_s* dcb);
extern int ql_uart_register_cb(ql_uart_port_number_e port, ql_uart_callback uart_cb);
extern int ql_uart_write(ql_uart_port_number_e port, unsigned char* data, unsigned int data_len);
extern int ql_uart_read(ql_uart_port_number_e port, unsigned char* data, unsigned int data_len);



// mqtt相关模拟功能 -----------------------------------------------------------------------------------------------
typedef enum
{
	/** Accepted */
	MQTT_CONNECT_ACCEPTED = 0,
	/** Refused protocol version */
	MQTT_CONNECT_REFUSED_PROTOCOL_VERSION = 1,
	/** Refused identifier */
	MQTT_CONNECT_REFUSED_IDENTIFIER = 2,
	/** Refused server */
	MQTT_CONNECT_REFUSED_SERVER = 3,
	/** Refused user credentials */
	MQTT_CONNECT_REFUSED_USERNAME_PASS = 4,
	/** Refused not authorized */
	MQTT_CONNECT_REFUSED_NOT_AUTHORIZED_ = 5,

	MQTT_CONNECT_TCP_CONNECTED_FAILURE = 254,

	MQTT_CONNECT_OUT_OF_MEMORY = 255,
	/** Disconnected */
	MQTT_CONNECT_DISCONNECTED = 256,
	/** Timeout */
	MQTT_CONNECT_TIMEOUT = 257
} mqtt_connection_status_e;

typedef enum {
	MQTTCLIENT_SUCCESS = 0,
	MQTTCLIENT_INVALID_PARAM = -1,
	MQTTCLIENT_WOUNDBLOCK = -2,
	MQTTCLIENT_OUT_OF_MEM = -3,
	MQTTCLIENT_ALLOC_FAIL = -4,
	MQTTCLIENT_TCP_CONNECT_FAIL = -5,
	MQTTCLIENT_NOT_CONNECT = -6,
	MQTTCLIENT_SEND_PKT_FAIL = -7,
	MQTTCLIENT_BAD_REQUEST = -8,
	MQTTCLIENT_TIMEOUT = -9,
}mqtt_error_code_e;

struct mqtt_ssl_config_t {
	int    ssl_ctx_id;
	int    verify_level;
	char* cacert_path;
	char* client_cert_path;
	char* client_key_path;
	char* client_key_pwd;
	int    ssl_version;
	int    sni_enable;
	int    ssl_negotiate_timeout;
	int    ignore_invalid_certsign;
	int    ignore_multi_certchain_verify;
	uint32_t  ignore_certitem;
	char* cacert_buffer;
	uint32_t   client_cert_type;
};
struct mqtt_connect_client_info_t {
	const char* client_id;
	/** User name, set to NULL if not used */
	const char* client_user;
	/** Password, set to NULL if not used */
	const char* client_pass;
	/** keep alive time in seconds, 0 to disable keep alive functionality*/
	unsigned short keep_alive;
	/** timeout of the packet delivery. Range: 1–60. Unit: s.*/
	unsigned char pkt_timeout;
	/** retry times when packet delivery times out. Range: 0–10.*/
	unsigned char retry_times;
	/** will topic, set to NULL if will is not to be used,
		will_msg, will_qos and will retain are then ignored */
	const char* will_topic;
	/** will_msg, see will_topic */
	const char* will_msg;
	/** will_qos, see will_topic */
	unsigned char will_qos;
	/** will_retain, see will_topic */
	unsigned char will_retain;
	unsigned char clean_session;
	struct mqtt_ssl_config_t* ssl_cfg;
};

struct simu_mqtt_client;
typedef struct simu_mqtt_client mqtt_client_t;
typedef void (*mqtt_connection_cb_t)(mqtt_client_t* client, void* arg, mqtt_connection_status_e status);
typedef void (*mqtt_request_cb_t)(mqtt_client_t* client, void* arg, int err);
typedef void (*mqtt_incoming_publish_cb_t)(mqtt_client_t* client, void* arg, int pkt_id, const char* topic, const unsigned char* payload, unsigned short payload_len);
typedef void (*mqtt_disconnect_cb_t)(mqtt_client_t* client, void* arg, int err);
typedef void(*mqtt_state_exception_cb_t)(mqtt_client_t* client);

struct simu_mqtt_client {
	struct mqtt_c_client client;
	uint8_t sendbuf[64 * 1024]; /* sendbuf should be large enough to hold multiple whole mqtt messages */
	uint8_t recvbuf[64 * 1024]; /* recvbuf should be large enough any whole mqtt message expected to be received */
	int sockfd;
	pthread_t tid;

	mqtt_state_exception_cb_t exp_cb;
	mqtt_incoming_publish_cb_t inpub_cb;
};
typedef struct
{
	uint32_t sec;
	uint32_t usec;
}ql_timeval_t;


// BLE(8910) related  ------------------------------------------------------------------------------------------------
#define QL_BLEADV_REAL_DATA_LEN             254         //256 - 2
#define QL_BLESCAN_MAX_REMOTE_NAME_LEN      32
#define QL_BLE_ADV_MIN_ADV                  0x300
#define QL_BLE_ADV_MAX_ADV                  0x320
#define QL_BLE_ADV_MAP                      0x07
#define QL_BLEADV_ADV_MAX                   0x4000
#define QL_BLEADV_ADV_MIN                   0x20

typedef enum
{
	QL_BLE_PUBLIC_ADDRESS = 0,        //public address
	QL_BLE_RANDOM_ADDRESS = 1,        //random address
}ql_ble_address_mode_e;
typedef struct
{
	unsigned char addr[6];
} ql_bt_addr_s;
typedef enum
{
	QL_BT_SUCCESS = 0,
	//
	QL_BT_ERROR = 1 | (QL_COMPONENT_BSP_BT << 16),
	QL_BT_PENDING,
	QL_BT_BUSY_ERR,
	QL_BT_NO_RESOURCE_ERR,
	QL_BT_NOT_FOUND_ERR,
	QL_BT_DEVICE_NOT_FOUND_ERR,
	QL_BT_CONNECTION_FAILED_ERR,
	QL_BT_TIMEOUT_ERR,
	QL_BT_NO_CONNECTION_ERR,
	QL_BT_INVALID_PARM_ERR,
	QL_BT_NOT_SUPPORTED_ERR,
	QL_BT_CANCELLED_ERR,
	QL_BT_IN_PROGRESS_ERR,
	QL_BT_RESTRICTED_ERR,
	QL_BT_INVALID_HANDLE_ERR,
	QL_BT_PACKET_TOO_SMALL_ERR,
	QL_BT_NO_PAIR_ERR,
	QL_BT_FAILED_ERR,
	QL_BT_DISCONNECT_ERR,
	QL_BT_NO_CONNECT_ERR,
	QL_BT_IN_USE_ERR,
	QL_BT_MEDIA_BUSY_ERR,
	QL_BT_OFF_ERR,

	//蓝牙协议栈返回的错误
	QL_BT_SYS_FAIL_ERR,                     //操作失败
	QL_BT_SYS_DONE_ERR,                     //处于完成状态
	QL_BT_SYS_PENDING_ERR,                  //处于等待状态
	QL_BT_SYS_INVALID_PARAM_ERR,            //输入的参数无效
	QL_BT_SYS_ISECFAIL_ERR,                 //安全连接失败
	QL_BT_SYS_FLOWCTRL_ERR,                 //处于流控状态
	QL_BT_SYS_NORESOURCES_ERR,              //资源不足
	QL_BT_SYS_UNSUPPORTED_ERR,              //设备或能力不支持
	QL_BT_SYS_HW_ERR,                       //蓝牙硬件错误
	QL_BT_SYS_HOST_ERR,                     //蓝牙主机错误
	QL_BT_SYS_UNKOWN_ERR,                   //蓝牙未知错误
	QL_BT_SYS_NOT_READY_ERR,                //处于未就绪状态
	QL_BT_SYS_READY_ERR,                    //处于就绪状态
	QL_BT_SYS_AUTHORISE_FAIL_ERR,           //授权失败
	QL_BT_SYS_AUTHEN_FAIL_ERR,              //认证失败
	QL_BT_SYS_ENCRYPT_FAIL_ERR,             //加密失败
	QL_BT_SYS_TIMEOUT_ERR,                  //操作超时
	QL_BT_SYS_PROTOCOL_ERR,                 //协议错误
	QL_BT_SYS_DISALLOWED_ERR,               //操作不允许
	QL_BT_SYS_BUFF_SAMLL_ERR,               //蓝牙协议栈buffer太小
	QL_BT_SYS_DISCONNECT_ERR,               //处于未连接
	QL_BT_SYS_MORE_ERR,                     //更多错误

	QL_BT_REGISTER_MSG_ERR,
	QL_BT_DISCONNECT,
	QL_BT_ALREADY_CONNECTED_ERR,            //已经建立了连接
	QL_BT_ALREADY_STARTED_ERR,
	QL_BT_ALREADY_STOPED_ERR,
	QL_BT_NOT_START_ERR,
	QL_BT_NOT_STOP_ERR,
	QL_BT_PRAMA_TYPE_ERR,
	QL_BT_PRAMA_LENGTH_ERR,
	QL_BT_PRAMA_DATA_ERR,                   //BT/BLE input parameter error
	QL_BT_PRAMA_SIZE_ERR,
	QL_BT_PRAMA_NULL_ERR,
	QL_BT_NOT_INQURY_ERR,
	QL_BT_SPP_NOT_CONNECT_ERR,
	QL_BT_SPP_NOT_SUPPORT_ERR,
	QL_BT_GET_PAIR_INFO_ERR,
	QL_BT_REMVOE_PAIR_INFO_ERR,
	QL_BT_GET_WHITELIST_ERR,
	QL_BT_MEM_ADDR_NULL_ERR,
	QL_BT_GET_FILE_ADDR_ERR,
	QL_BT_WIFI_USING_ERR,
	QL_BT_NOT_INIT_ERR,
	QL_BT_NOT_REGISTER_CB_ERR,
	QL_BT_TASK_NOT_EXIT_ERR,
	QL_BT_IS_USING_ERR,
	QL_BT_ALREADY_REGISTERED_ERR,
	QL_BT_SERVICE_ALREADY_EXITED_ERR,
	QL_BT_SERVICE_NOT_EXITED_ERR,
	QL_BT_SERVICE_NOT_CLEAN_ERR,                    //服务没有清除，service not clean
	QL_BT_CHARA_ALREADY_EXITED_ERR,
	QL_BT_CHARA_NOT_EXITED_ERR,
	QL_BT_NOT_CONN_ID_ERR,
	QL_BLE_PUBLIC_ADDR_NOT_USED_ERR,                //cannot use ble public address
	QL_BLE_CID_ERR,                                 //没有对应cid的通道
	QL_BLE_HANDLE_ERR,                              //使用了错误的句柄
	QL_BLE_PROP_ERR,                                //属性错误
	QL_BLE_WRITE_NAME_FILE_ERR,                     //写蓝牙名称文件错误
	QL_BLE_READ_NAME_FILE_ERR,                      //读蓝牙名称文件错误
	QL_BLE_READ_ADDR_FILE_ERR,                      //read mac address file err
	//bt hfp error
	QL_BT_HFP_CONNECTED_ERR = 100 | (QL_COMPONENT_BSP_BT << 16),    //bt hfp:already connected
	QL_BT_HFP_NOT_CONN_ADDR_ERR,                                    //bt hfp:not the same address whih connected address
	QL_BT_HFP_NOT_CONNECTED_ERR,                                    //bt hfp:not connected
	QL_BT_HFP_NOT_OPERATION_ERR,                                    //bt hfp:operation not support

	//bt audio error
	QL_BT_AUDIO_SEND_MSG_ERR = 200 | (QL_COMPONENT_BSP_BT << 16),    //bt audio:seng msg to queue failed

	//bt a2dp error
	QL_BT_A2DP_CONNECT_ERR = 300 | (QL_COMPONENT_BSP_BT << 16),     //bt a2dp:connect failed
	QL_BT_A2DP_DISCONNECT_ERR,                                      //bt a2dp:disconnect failed

	//bt avrcp error
	QL_BT_AVRCP_INVALID_ADDR_ERR = 400 | (QL_COMPONENT_BSP_BT << 16),       //bt avrcp:invalid addr error
	QL_BT_AVRCP_DISCONNECT_ERR,                                             //bt avrcp:disconnect error
	QL_BT_AVRCP_OPT_ERR,                                                    //bt avrcp:operation error
	QL_BT_AVRCP_INVALID_PARAM_ERR,                                          //bt avrcp:invalid param error

	//bt filter error
	QL_BT_FILTER_PARAM_ERR = 500 | (QL_COMPONENT_BSP_BT << 16),             //bt filter:param error
}ql_errcode_bt_e;
typedef void (*ql_bt_callback)(void* ind_msg_buf, void* ctx);
typedef enum
{
	QL_BT_BLE_NAME_CODE_UTF8 = 0,                   //code utf8
	QL_BT_BLE_NAME_CODE_GBK,                       //code GBK
}ql_bt_ble_name_code_type_e;
typedef struct
{
	unsigned char name[22 + 1];  //蓝牙名称实际长度，最大长度为22.end with \0
	ql_bt_ble_name_code_type_e code_type;
}ql_bt_ble_local_name_s;
typedef enum
{
	QL_BLEADV_INV = 0,    //可连接的非定向广播，默认选择
	QL_BLEADV_HDCDA = 1,    //可连接高占空比的定向广播    
	QL_BLEADV_SCAN_IND = 2,    //可扫描的非定向广播
	QL_BLEADV_NONCONN_IND = 3,    //不可连接的非定向广播
	QL_BLEADV_LDCDA = 4,    //可连接低占空比的定向广播
}ql_bleadv_type_info_e;
typedef enum
{
	QL_BLEADV_FILTER_0 = 0,            //处理所有设备的扫描和连接请求
	QL_BLEADV_FILTER_1 = 1,            //处理所有设备的连接请求和只处理白名单设备的扫描请求
	QL_BLEADV_FILTER_2 = 2,            //处理所有设备的扫描请求和只处理白名单设备的连接请求
	QL_BLEADV_FILTER_3 = 3,            //只处理白名单设备的连接和扫描请求
}ql_bleadv_fliter_info_e;
typedef struct
{
	unsigned int max_adv;                                       //广播最大间隔：范围0x0020-0x4000。gap 0.625ms, 20ms-10.24s
	unsigned int min_adv;                                       //广播最小间隔：范围0x0020-0x4000。gap 0.625ms, 20ms-10.24s
	ql_bleadv_type_info_e adv_type;                             //广播类型
	unsigned char own_addr_type;                                //本地地址类型。0-公共地址，1-随机地址
	unsigned char channel_map;                                  //广播通道。bit0-37，bit1-38，bit2-39。默认3个信道都选择
	ql_bleadv_fliter_info_e filter;                             //广播过滤策略
	unsigned char discov_mode;                                  //发现模式，GAP协议使用，默认为1(普通发现模式)
	unsigned char no_br_edr;                                    //不用BR/EDR，默认为1
	unsigned char enable_adv;                                   //使能广播，默认为1
}ql_bleadv_param_s;

typedef struct
{
	unsigned char date_len;                                     //广播数据长度，不超过31个字节
	unsigned char data[31];              //广播数据             
}ql_bleadv_set_data_s;

extern ql_errcode_bt_e ql_bt_ble_get_nv_addr(ql_bt_addr_s* mac_addr);
extern ql_errcode_bt_e ql_ble_gatt_server_init(ql_bt_callback bt_cb);
extern ql_errcode_bt_e ql_bt_start();
extern ql_errcode_bt_e ql_bt_ble_set_localname(ql_bt_ble_local_name_s local_name);
extern ql_errcode_bt_e ql_bleadv_set_param(ql_bleadv_param_s adv_param);
extern ql_errcode_bt_e ql_bleadv_set_data(ql_bleadv_set_data_s avd_data);
extern ql_errcode_bt_e ql_bleadv_start();
extern ql_errcode_bt_e ql_bt_stop();
extern ql_errcode_bt_e ql_ble_gatt_server_release();



extern int ql_bind_sim_and_profile(uint8_t nSim, int profile_idx, uint16_t* sim_cid);
extern int ql_mqtt_client_init(mqtt_client_t* client, int cid);
extern int ql_mqtt_connect(mqtt_client_t* client, const char* host, mqtt_connection_cb_t cb, void* arg, const struct mqtt_connect_client_info_t* client_info, mqtt_state_exception_cb_t exp_cb);
extern int ql_mqtt_sub_unsub(mqtt_client_t* client, const char* topic, unsigned char qos, mqtt_request_cb_t cb, void* arg, unsigned char sub);
extern int ql_mqtt_publish(mqtt_client_t* client, const char* topic, const void* payload, unsigned short payload_length, unsigned char qos, unsigned char retain, mqtt_request_cb_t cb, void* arg);
extern int ql_mqtt_disconnect(mqtt_client_t* client, mqtt_disconnect_cb_t cb, void* arg);
extern QlOSStatus ql_gettimeofday(ql_timeval_t* timeval);

// simulate timer function, current only support interrupt mode and only support 1 instance
typedef uint32_t ql_timer_t;
extern QlOSStatus ql_rtos_timer_create(ql_timer_t* timerRef, ql_task_t taskRef, void (*callBackRoutine)(void*),	void* timerArgc);
extern QlOSStatus ql_rtos_timer_start(ql_timer_t timerRef, uint32_t set_Time, unsigned char	cyclicalEn);

extern int ql_gpio_set_level(ql_GpioNum gpio_num, ql_LvlMode gpio_lvl);
extern int ql_pin_set_func(uint8_t pin_num, uint8_t func_sel);
extern int ql_gpio_init(ql_GpioNum gpio_num, ql_GpioDir gpio_dir, ql_PullMode gpio_pull, ql_LvlMode gpio_lvl);
extern int ql_dev_feed_wdt(void);
extern int ql_dev_get_firmware_version(char* p_version, size_t version_len);
extern ql_errcode_wifi_scan_e ql_wifiscan_register_cb(void * wifiscan_cb);
extern void ql_wifiscan_async_start(void);
extern ql_errcode_wifi_scan_e ql_wifiscan_async(void);
extern QlOSStatus ql_event_try_wait(ql_event_t* event_strc);
#define QL_LOG_PRINTF_TAG(level, tag, fmt, ...)                                          \
    do                                                                          \
    {                                                                           \
        if (QL_LOG_OUTPUT_LEVEL >= level)                                       \
            printf(fmt, ##__VA_ARGS__);   \
    } while (0)


extern char* strnstr(char* org, char *target, int len);
#endif //__SIMU_EC800_H_